home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 4 / FM Towns Free Software Collection 4 - Disc 1.iso / t_os / kenban / kenban.c next >
Text File  |  1991-10-18  |  12KB  |  532 lines

  1. /***************************************************************************
  2.  
  3.        TMENU.IF2 登録用  .FMB/.PMB 試聴プログラム  Ver 1.0
  4.  
  5.                  1990/12/01     HONESEN (自来也愛好会)
  6.  
  7. ***************************************************************************/
  8.  
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <egb.h>
  14. #include <mos.h>
  15. #include <snd.h>
  16.  
  17.  
  18. #define ON    1
  19. #define OFF    0
  20. #define FM    0
  21. #define PCM    64
  22.  
  23.  
  24. struct    name {
  25.     short    x, y;
  26.     short    len;
  27.     char    nam[9];
  28. };
  29.  
  30.  
  31. /**** BIOS ワークエリア ****/
  32.  
  33. char    eWork[1536],
  34.     mWork[4096],
  35.     sWork[16384];
  36.  
  37. /**** 共通変数エリア、テーブル ****/
  38.  
  39. int    ch;        /* チャンネル番号 FM:0 / PCM:64 */
  40. struct name    tone[128],
  41.         fsw[]  = {{0, 0, 4, "DOWN"},
  42.                   {0, 0, 4, " UP "},
  43.                   {0, 0, 4, "EXIT"}};
  44.  
  45. int    xy[][4] =      {{320,   8, 367,  31},        /* DOWN */
  46.             {375,   8, 422,  31},        /*  UP  */
  47.             {470,   8, 517,  31},        /* EXIT */
  48.             {  0,  72, 639, 167},        /* TONE */
  49.             { 48, 236, 635, 315},        /* KEYh */
  50.             {  4, 380, 591, 459}};        /* KEYl */
  51.  
  52. int    b_key[] = {12,25, 37,50, 75,88, 98,111, 121,134};
  53. int    p_key[] = {10,20,30,40,55,70,80,92,100,115,125,140};
  54. int    white[] = {0, 2, 4, 5, 7, 9, 11},
  55.     black[] = {1, 3, 6, 8, 10};
  56.  
  57. int    base, offset, ch_flg, crnt_key, w_or_b;
  58.  
  59. int    cpybuf[10000];
  60.  
  61. /*------------ bload : FM/PCM 音色ファイル読み込み関数 -----------------*/
  62.  
  63. bload(path)        /* ret = 成功:0 / 失敗:1 */
  64. char    *path;        /* ファイル名 */
  65. {
  66.     char    *p, dum[8];
  67.     int    l;
  68.  
  69.     if ((l=strlen(path)) > 4) {
  70.         p = path + l - 4;
  71.         if (!strcmp(p,".fmb") || !strcmp(p,".FMB")) {
  72.             if (!SND_fm_bank_load(path,dum)) {
  73.                 ch = FM;
  74.                 return(0);
  75.             }
  76.         }
  77.         else if (!strcmp(p,".pmb") || !strcmp(p,".PMB")) {
  78.             if (!SND_pcm_bank_load(path,dum)) {
  79.                 ch = PCM;
  80.                 return(0);
  81.             }
  82.         }
  83.     }
  84.     return(1);
  85. }
  86.  
  87. /*----------- get_tname : 音色名を tone[] に読み込む関数---------*/
  88.  
  89. void get_tnam()
  90. {
  91.     char    buf[128], *p, *q;
  92.     int    i;
  93.  
  94.     for (i=0; i<(ch==FM? 128: 32); i++) {
  95.         SND_inst_read(ch, i, buf);
  96.         buf[8] = '\0';
  97.         tone[i].len = 0;
  98.         p = tone[i].nam;  q = buf;
  99.         while ((*p++=*q++) >= ' ') tone[i].len++;
  100.         *(p-1) = '\0';
  101.     }
  102. }
  103.  
  104. /*------------------- box : 矩形描画関数 ------------------------*/
  105.  
  106. void box(x1, y1, x2, y2, c)
  107. int    x1, y1, x2, y2;        /* 対角線座標 */
  108. int    c;
  109. {
  110.     short    para[32];
  111.  
  112.     MOS_disp(0);
  113.     EGB_color(eWork, 0, c); EGB_color(eWork, 2, c);
  114.     para[0] = x1;    para[1] = y1;
  115.     para[2] = x2;    para[3] = y2;
  116.     EGB_rectangle(eWork, (char*)para);
  117.     MOS_disp(1);
  118. }
  119.  
  120. /*------------------- pset : 点描画関数 ------------------------*/
  121.  
  122. void pset(x, y, c)
  123. int    x, y;            /* 座標 */
  124. int    c;
  125. {
  126.     short    para[32];
  127.  
  128.     MOS_disp(0);
  129.     EGB_color(eWork, 0, c);
  130.     para[0] = 1;
  131.     para[1] = x;    para[2] = y;
  132.     EGB_pset(eWork, (char*)para);
  133.     MOS_disp(1);
  134. }
  135.  
  136. /*----------------- button : ボタンの縁取り関数 ----------------*/
  137.  
  138. void button(x1, y1, x2, y2, c1, c2)
  139. int    x1, y1, x2, y2,        /* 対角線座標 */
  140.     c1,            /* 左上の色 */
  141.     c2;            /* 右下の色 */
  142. {
  143.     short    para[32];
  144.  
  145.     MOS_disp(0);
  146.     EGB_color(eWork, 0, c1);
  147.     para[0] = 3;
  148.     para[1] = x1;    para[2] = y2;
  149.     para[3] = x1;    para[4] = y1;
  150.     para[5] = x2-1;    para[6] = y1;
  151.     EGB_connect(eWork, (char*)para);
  152.  
  153.     EGB_color(eWork, 0, c2);
  154.     para[0] = 7;
  155.     para[1] = x2;    para[2] = y2;
  156.     para[3] = x2;    para[4] = y1;
  157.     para[5] = x2-1;    para[6] = y1+1;
  158.     para[7] = x2-1;    para[8] = y2-1;
  159.     para[9] = x1+1;    para[10] = y2-1;
  160.     para[11] = x1+1;para[12] = y2;
  161.     para[13] = x2;  para[14] = y2;
  162.     EGB_connect(eWork, (char*)para);
  163.     MOS_disp(1);
  164. }
  165.  
  166. /*-------------- sw_on_off : ボタンのオン・オフ関数 ------------------*/
  167.  
  168. void sw_on_off(x1, y1, x2, y2, s, f1, f2)
  169. int    x1, y1, x2, y2;        /* 対角線座標 */
  170. struct name    *s;        /* キートップ文字列 */
  171. int    f1, f2;            /* ON / OFF */
  172. {
  173.     int    c1, c2, sc;
  174.  
  175.     if (f1 == ON) {
  176.         c1 = 8; c2 = 15; sc = 12;
  177.     }
  178.     else {
  179.         c1 = 15; c2 = 8; sc = 0;
  180.     }
  181.     EGB_textZoom(eWork, 0, 8, 16);
  182.     EGB_fontStyle(eWork, 0);
  183.  
  184.     if (f2) button(x1, y1, x2, y2, c1, c2);
  185.     s->x = x1 + 8; s->y = y2 - 3;
  186.     EGB_color(eWork, 0, sc);
  187.     MOS_disp(0);
  188.     EGB_sjisString(eWork, (char*)s);
  189.     MOS_disp(1);
  190. }
  191.  
  192. /*------------- disp_one_sw : 音色スイッチ表示関数 -----------------*/
  193.  
  194. void disp_one_sw(f1, f2)
  195. int    f1, f2;
  196. {
  197.     int    x, y;
  198.  
  199.     x = (offset/4)*80 + xy[3][0] + 1;
  200.     y = (offset%4)*24 + xy[3][1] + 1;
  201.     box(x, y, x+75, y+19, 7);
  202.     sw_on_off(x-1, y-1, x+77, y+21, &tone[base+offset], f1, f2);
  203. }
  204.  
  205. /*------------- disp_all_sw : 全音色スイッチ表示関数 -----------------*/
  206.  
  207. void disp_all_sw(f2)
  208. int    f2;
  209. {
  210.     int    i;
  211.     struct name    s;
  212.  
  213.     for (offset=0; offset<32; offset++) {
  214.         disp_one_sw(OFF, f2);
  215.     }
  216.     offset = 0;
  217.     disp_one_sw(ON, 1);
  218.     box(0, 52, 639, 71, 5);
  219.     EGB_textZoom(eWork, 0, 8, 16);
  220.     EGB_fontStyle(eWork, 1);
  221.     EGB_color(eWork, 0, 3);
  222.     s.len = 3;  s.y = 70;
  223.     for (i=0; i<32; i+=4) {
  224.         s.x = i * 20 + 32;
  225.         s.nam[0] = (base+i+1)/100 + '0';
  226.         s.nam[1] = (base+i+1)%100/10 + '0';
  227.         s.nam[2] = (base+i+1)%10 + '0';
  228.         MOS_disp(0);
  229.         EGB_sjisString(eWork, (char*)&s);
  230.         MOS_disp(1);
  231.     }
  232.     SND_inst_change(ch, base);  SND_inst_change(ch+1, base);
  233.     SND_inst_change(ch+2, base);  SND_inst_change(ch+3, base);
  234. }
  235.  
  236. /*-------------------- disp_key : 鍵盤表示 ---------------------------*/
  237.  
  238. void disp_key()
  239. {
  240.     short    para[32], symbuf[4];
  241.     int    i, x, y, o;
  242.  
  243.     box(xy[4][0],xy[4][1]-20,xy[4][0]+146,xy[4][1]-1, 7);
  244.     button(xy[4][0],xy[4][1]-20,xy[4][0]+146,xy[4][1]-1, 15, 8);
  245.                                 /*白鍵*/
  246.     MOS_disp(0);
  247.     EGB_color(eWork, 0, 0);   EGB_color(eWork, 2, 15);
  248.     para[0] = 6;
  249.     para[2] = 236;    para[4] = 312;    para[6] = 315;
  250.     para[8] = 315;    para[10] = 312;    para[12] = 236;
  251.     for (i=xy[4][0]; i<xy[4][0]+21*7; i+=21) {
  252.         para[1] = i;    para[3] = i;    para[5] = i+3;
  253.         para[7] = i+17;    para[9] = i+20;    para[11] = i+20;
  254.         EGB_polygon(eWork, (char*)para);
  255.     }
  256.                                 /*黒鍵*/
  257.     for (i=0; i<10; i+=2) {
  258.         x = xy[4][0] + b_key[i];
  259.         box(x,235,x+1,283, 7);
  260.         box(x+12,235,x+13,283, 8);
  261.         box(x+2,284,x+11,285, 8);
  262.         box(x+2,235,x+11,283, 0);
  263.         pset(x+1,284,8);
  264.         pset(x+12,284,0);
  265.         pset(x,235,8);
  266.     }
  267.                                 /*コピー*/
  268.     MOS_disp(0);
  269.     *(int**)para = cpybuf;
  270.     para[2] = 0x14;
  271.     para[3] = xy[4][0]; para[4] = xy[4][1]-20;
  272.     para[5] = xy[4][0]+146; para[6] = xy[4][3];
  273.     EGB_getBlock(eWork, (char*)para);
  274.     EGB_color(eWork, 0, 14);  EGB_color(eWork, 1, 8);
  275.     EGB_fontStyle(eWork, 5);
  276.     EGB_textZoom(eWork, 0, 16, 16);
  277.     symbuf[2] = 1;
  278.     y = xy[4][1]-20;  o = 4;
  279.     for (x=xy[4][0]; x<xy[4][0]+21*28; x+=21*7) {
  280.         para[3] = x;  para[4] = y;
  281.         para[5] = x+146;  para[6] = y+99;
  282.         EGB_putBlock(eWork, 0, (char*)para);
  283.         symbuf[0] = x+65; symbuf[1] = y+17;
  284.         *(char*)(symbuf+3) = o + '0';
  285.         EGB_sjisString(eWork, (char*)symbuf);
  286.         o++;
  287.     }
  288.     y = xy[5][1]-20;  o = 0;
  289.     for (x=xy[5][0]; x<xy[5][0]+21*28; x+=21*7) {
  290.         para[3] = x;  para[4] = y;
  291.         para[5] = x+146;  para[6] = y+99;
  292.         EGB_putBlock(eWork, 0, (char*)para);
  293.         symbuf[0] = x+65; symbuf[1] = y+17;
  294.         *(char*)(symbuf+3) = o + '0';
  295.         EGB_sjisString(eWork, (char*)symbuf);
  296.         o++;
  297.     }
  298.     MOS_disp(1);
  299. }
  300.  
  301. /*----------------- disp_tnam : 音色ファイル名の表示 -----------------*/
  302.  
  303. void disp_tnam(nam)
  304. char    *nam;
  305. {
  306.     short    para[64];
  307.  
  308.     EGB_color(eWork, 0, 1);
  309.     EGB_fontStyle(eWork, 1);
  310.     EGB_textZoom(eWork, 0, 8, 16);
  311.     para[0] = 8;  para[1] = 28;
  312.     strcpy((char*)para+6, nam);
  313.     para[2] = strlen(nam);
  314.     if (para[2] > 38) para[2] = 38;
  315.     EGB_sjisString(eWork, (char*)para);
  316. }
  317.  
  318. /*--------------- paint_key : 鍵盤ペイント関数 ------------------------*/
  319.  
  320. void paint_key(n, c)
  321. int    n, c;
  322. {
  323.     short    para[32];
  324.  
  325.     para[0] = ((n >= 60)?    xy[4][0] + 21*7*((n-60)/12) + p_key[n%12]:
  326.                 xy[5][0] + 21*7*((n-12)/12) + p_key[n%12]);
  327.     para[1] = ((n >= 60)?    xy[4][1]+2: xy[5][1]+2);
  328.     MOS_disp(0);
  329.     EGB_color(eWork, 2, c);
  330.     EGB_closePaint(eWork, (char*)para);
  331.     MOS_disp(1);
  332. }
  333.  
  334. /*------------------ key_off : キーオフ関数 ---------------------------*/
  335.  
  336. void key_off()
  337. {
  338.     if (crnt_key != -1) {
  339.         paint_key(crnt_key, w_or_b);
  340.         SND_key_off(ch+ch_flg++);
  341.         ch_flg &= 3;
  342.         crnt_key = -1;
  343.     }
  344. }
  345.  
  346. /*------------------ key_exit : "EXIT"キー関数 -----------------------*/
  347.  
  348. void key_exit()
  349. {
  350.     int    b, x, y;
  351.  
  352.     key_off();
  353.     sw_on_off(xy[2][0],xy[2][1],xy[2][2],xy[2][3],&fsw[2],ON,1);
  354.     while (MOS_rdpos(&b,&x,&y),b);
  355.     sw_on_off(xy[2][0],xy[2][1],xy[2][2],xy[2][3],&fsw[2],OFF,1);
  356. }
  357.  
  358. /*------------------ key_down : "DOWN"キー関数 -----------------------*/
  359.  
  360. void key_down()
  361. {
  362.     int    b, x, y;
  363.  
  364.     key_off();
  365.     sw_on_off(xy[0][0],xy[0][1],xy[0][2],xy[0][3],&fsw[0],ON,1);
  366.     if (ch == FM) {
  367.         if (base > 31) {
  368.             disp_one_sw(OFF, 1);
  369.             base -= 32;
  370.             disp_all_sw(0);
  371.         }
  372.     }
  373.     while (MOS_rdpos(&b,&x,&y),b);
  374.     sw_on_off(xy[0][0],xy[0][1],xy[0][2],xy[0][3],&fsw[0],OFF,1);
  375.     SND_inst_change(ch, base);  SND_inst_change(ch+1, base);
  376.     SND_inst_change(ch+2, base);  SND_inst_change(ch+3, base);
  377. }
  378.  
  379. /*-------------------- key_up : "UP"キー関数 -------------------------*/
  380.  
  381. void key_up()
  382. {
  383.     int    b, x, y;
  384.  
  385.     key_off();
  386.     sw_on_off(xy[1][0],xy[1][1],xy[1][2],xy[1][3],&fsw[1],ON,1);
  387.     if (ch == FM) {
  388.         if (base < 96) {
  389.             disp_one_sw(OFF, 1);
  390.             base += 32;
  391.             disp_all_sw(0);
  392.         }
  393.     }
  394.     while (MOS_rdpos(&b,&x,&y),b);
  395.     sw_on_off(xy[1][0],xy[1][1],xy[1][2],xy[1][3],&fsw[1],OFF,1);
  396.     SND_inst_change(ch, base);  SND_inst_change(ch+1, base);
  397.     SND_inst_change(ch+2, base);  SND_inst_change(ch+3, base);
  398. }
  399.  
  400. /*------------ key_tchg : 音色切り替えキー関数 -----------------------*/
  401.  
  402. void key_tchg(x, y)
  403. int    x, y;
  404. {
  405.     int    b, x1, y1;
  406.  
  407.     key_off();
  408.     disp_one_sw(OFF, 1);
  409.     offset = (x/80)*4 + (y-xy[3][1])/24;
  410.     disp_one_sw(ON, 1);
  411.     while (MOS_rdpos(&b,&x1,&y1),b);
  412.     SND_inst_change(ch, base+offset);  SND_inst_change(ch+1, base+offset);
  413.     SND_inst_change(ch+2, base+offset); SND_inst_change(ch+3, base+offset);
  414. }
  415.  
  416. /*------------------ key_on : キーオン関数 ---------------------------*/
  417.  
  418. void key_on(x, y, o)
  419. int    x, y, o;
  420. {
  421.     int    i, j, k, w;
  422.  
  423.     o += x / 147; x %= 147;
  424.     i = white[x/21]; 
  425.     w = 15;
  426.     if (y < 50) {
  427.         for (j=0; j<10&&(x<b_key[j]||b_key[j+1]<x); j+=2);
  428.         if (j < 10) {
  429.             i = black[j/2];
  430.             w = 0;
  431.         }
  432.     }
  433.     k = (o+1)*12 + i;
  434.     if (crnt_key == -1) {
  435.         SND_key_on(ch+ch_flg, k, 100);
  436.         paint_key(k, 10);
  437.         crnt_key = k;
  438.         w_or_b = w;
  439.     }
  440.     else if (crnt_key != k ) {
  441.         key_off();
  442.         SND_key_on(ch+ch_flg, k, 100);
  443.         paint_key(k, 10);
  444.         crnt_key = k;
  445.         w_or_b = w;
  446.     }
  447. }
  448.  
  449. /*--------------------- main : メイン関数 ----------------------------*/
  450.  
  451. void main(argc, argv)
  452. int    argc;
  453. char    *argv[];
  454. {
  455.  
  456.     int    i, mb, mx, my;
  457.  
  458. /**** サウンド初期設定 ****/
  459.  
  460.     SND_init(sWork);
  461.     SND_elevol_init();
  462.     SND_elevol_mute(3);
  463.  
  464. /**** 音色ファイルの読み込み ****/
  465.  
  466.     if (argc==0 || bload(argv[1])) goto end;
  467.     get_tnam();
  468.  
  469. /**** グラフィック初期設定 ****/
  470.  
  471.     EGB_init(eWork, 1536);
  472.     EGB_displayPage(eWork, 0, 0);
  473.     EGB_paintMode(eWork, 0x0022);
  474.  
  475. /**** マウス初期設定 ****/
  476.  
  477.     MOS_start(mWork, 4096);
  478.     MOS_horizon(0, 639);
  479.     MOS_vertical(0, 479);
  480.     MOS_setpos(320, 240);
  481.     MOS_disp(1);
  482.  
  483. /**** 画面初期設定 ****/
  484.                             /* 背景 */
  485.     box(0, 0, 639, 479, 5);
  486.                             /* DOWN UP EXIT */
  487.     for (i=0; i<3; i++) {
  488.         box(xy[i][0], xy[i][1], xy[i][2], xy[i][3], 7);
  489.         sw_on_off(xy[i][0], xy[i][1], xy[i][2], xy[i][3], 
  490.                             &fsw[i], OFF, 1);
  491.     }
  492.                             /* 音色スイッチ表示 */
  493.     base = 0;
  494.     disp_all_sw(1);
  495.                             /* 鍵盤表示 */
  496.     disp_key();
  497.                             /* ファイル名表示 */
  498.     disp_tnam(argv[1]);
  499.     EGB_displayPage(eWork, 1, 3);
  500.  
  501. /**** マウス入力ループ ****/
  502.  
  503.     crnt_key = -1;  ch_flg = 0;
  504.     while (1) {
  505.         while (MOS_rdpos(&mb, &mx, &my), mb==0) key_off();
  506.         for (i=0; i<6&&(mx<xy[i][0]||xy[i][2]<mx
  507.                     ||my<xy[i][1]||xy[i][3]<my); i++);
  508.         switch (i) {
  509.             case 0 : key_down();
  510.                  break;
  511.             case 1 : key_up();
  512.                  break;
  513.             case 2 : key_exit();
  514.                  goto end;
  515.             case 3 : key_tchg(mx, my);
  516.                  break;
  517.             case 4 : key_on(mx-xy[4][0], my-xy[4][1], 4);
  518.                  break;
  519.             case 5 : key_on(mx-xy[5][0], my-xy[5][1], 0);
  520.                  break;
  521.             default: key_off();
  522.                  break;
  523.         }
  524.     }
  525.  
  526. /**** 終了 ****/
  527. end:
  528.     MOS_end();
  529.     SND_elevol_mute(0);
  530.     SND_end();
  531. }
  532.